﻿// /*
//  * @Author: Dreamy Icecream 
//  * @Date: 2021-01-06 15:19:13 
//  * @Description: 深度贴图动态模糊
//  * @Last Modified by: Dreamy Icecream 
//  * @Last Modified time: 2021-01-06 15:19:13 
//  */

Shader "Custom/MotionBlurWithDepthTexture" {

    Properties {
        _MainTex ("Base (RGB)", 2D) = "whtie" {}
        _BlurSize ("Blur Size", Float) = 1.0
    }

    SubShader {
        
        CGINCLUDE

            #include "UnityCG.cginc"

            sampler2D _MainTex;
            half4 _MainTex_TexelSize;
            sampler2D _CameraDepthTexture;
            float4x4 _CurrentViewProjectionInverseMaterix;
            float4x4 _PreviousViewProjectionMatrix;
            half _BlurSize;
            
            struct v2f {
                float4 pos : SV_POSITION;
                half4 uv : TEXCOORD0;
            };

            v2f vert(appdata_img v) {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);

                o.uv.xy = v.texcoord;
                o.uv.zw = v.texcoord;

                #if UNITY_UV_STARTS_AT_TOP
                    if(_MainTex_TexelSize.y < 0){
                        o.uv.z = 1 - o.uv.z;
                    }
                #endif

                return o;
            }

            fixed4 frag(v2f i) : SV_TARGET {
                //此像素的深度值
                float d = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.zw);

                //此像素的视角空间位置齐次处理
                float4 H = float4(i.uv.x * 2 - 1, i.uv.y * 2 - 1, d * 2 - 1, 1);

                float4 D = mul(_CurrentViewProjectionInverseMaterix, H);    

                //得到世界位置
                float4 worldPos = D / D.w;

                //当前的视角空间位置
                float4 currentPos = H;

                //计算上一帧的位置，齐次处理
                float4 previousPos = mul(_PreviousViewProjectionMatrix, worldPos);  
                previousPos /= previousPos.w;
                
                //使用此帧位置、上一帧位置计算像素速度
                float2 velocity = (currentPos.xy - previousPos.xy) / 2.0f;

                float2 uv = i.uv.xy;
                float4 c = tex2D(_MainTex, uv);
                uv += velocity * _BlurSize;

                for(int it = 1; it < 3; it++, uv += velocity * _BlurSize){
                    float4 currentColor = tex2D(_MainTex, uv);
                    c += currentColor;
                }

                c /= 3;

                return fixed4(c.rgb, 1.0);
            }

        ENDCG

        Pass{

            ZTest Always Cull Off ZWrite Off

            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag

            ENDCG
        }
    
    }

    FallBack Off
}
